package gee

import (
	"log"
	"net/http"
	"strings"
)

type HandlerFunc func(http.ResponseWriter, *http.Request)

type Engine struct {
	router map[string]HandlerFunc
}

func New() *Engine {
	engine := &Engine{router: make(map[string]HandlerFunc)}
	engine.Get("/favicon.ico", func(rw http.ResponseWriter, r *http.Request) {
		rw.Header().Add("Content-Type", "image/gif")
		rw.Write([]byte(""))
	})
	return engine
}

func getRouterKey(method string, path string) string {

	return strings.Join([]string{method, path}, ":")
}

func (engine *Engine) AddRouter(method string, path string, handler HandlerFunc) {

	engine.router[getRouterKey(method, path)] = handler
}

func (engine *Engine) Get(path string, handler HandlerFunc) {

	engine.AddRouter(http.MethodGet, path, handler)
}

func (engine *Engine) Post(path string, handler HandlerFunc) {

	engine.AddRouter(http.MethodPost, path, handler)
}

func (engine *Engine) Run(addr string) {

	log.Printf("Start server at %s...\n", addr)
	err := http.ListenAndServe(addr, engine)
	if err != nil {
		log.Fatalf("Server run failed: %s\n", err.Error())
	}
}

func (engine *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {

	path := r.URL.Path
	routerKey := getRouterKey(r.Method, r.URL.Path)
	handler, ok := engine.router[routerKey]
	if !ok {
		log.Printf("404: path not found - %s\n", path)
		w.WriteHeader(404)
		return
	}
	log.Printf("handle path - %s\n", path)
	handler(w, r)
}
